<template>
  <div>
    <div
      class="ant-input tag-box"
      tabindex="0"
      :class="{ backgroundColor: disabled }"
      @click="openModal()"
    >
      <div class="prompt-box">
        <template v-if="hasChoosedUser.length">
          <a-tag
            v-for="item in hasChoosedUser"
            :key="item.value"
            closable
            @close="() => handleTagClose(item.value)"
          >
            {{ item.label }}
          </a-tag>
        </template>
        <div v-else>{{ placeholder }}</div>
      </div>
    </div>
    <t-modal
      :title="title"
      :width="800"
      :visible="visible"
      wrapClassName="t-popup-modal"
      cancelText="关闭"
      :destroyOnClose="true"
      @ok="handleOk"
      @cancel="handleCancel"
    >
      <div class="transfer-body">
        <div class="transfer-pane">
          <div class="transfer-pane-tools">
            <a-row style="width: 100%">
              <a-input-search
                :placeholder="searchPlaceholder"
                style="width: 100%"
                @search="onSearch"
                v-model="userName"
              />
            </a-row>
          </div>
          <div class="transfer-pane-body">
            <a-checkbox-group
              @change="checkBoxChange"
              v-model="people"
              name="checkboxgroup"
              :options="peoleOptions"
            />
          </div>
        </div>
        <div class="divider-box"></div>
        <div class="transfer-pane">
          <div class="transfer-pane-tools">
            <span
              >已选择({{
                hasChoosedUser.length ? hasChoosedUser.length : 0
              }})</span
            >
            <span @click="resetSingle()" class="delete-button">清空</span>
          </div>
          <div class="transfer-pane-body">
            <template v-for="item in hasChoosedUser">
              <a-tag
                :key="item.value"
                closable
                @close="() => handleTagClose(item.value)"
              >
                {{ item.label }}
              </a-tag>
            </template>
          </div>
        </div>
      </div>
    </t-modal>
  </div>
</template>

<script>
export default {
  components: {},
  model: {
    prop: "value",
    event: "change",
  },
  props: {
    value: "",
    title: {
      type: String,
      default: "专家列表",
    },
    multiple: {
      type: Boolean,
      default: false,
    },
    url: {
      type: String,
      default: "",
    },
    placeholder: {
      type: String,
      default: "请选择",
    },
    searchPlaceholder: {
      type: String,
      default: "请输入",
    },
    disabled: {
      type: Boolean,
      default: false,
    },
  },
  watch: {
    value: {
      deep: true,
      immediate: true,
      handler(val) {
        if (val) {
          this.getData();
        }
      },
    },
  },
  data() {
    return {
      cloneData: [],
      visible: false,
      peoleOptions: [],
      people: [],
      hasChoosedUser: [],
      notChoosedUser: [],
      userName: "",
      cloneHasUser: [],
      clonePeople: [],
    };
  },
  mounted() {},
  methods: {
    setForm() {
      if (this.value) {
        if (!this.multiple) {
          //编辑：单选  回显
          this.hasChoosedUser = this.peoleOptions.filter(
            (v) => v.value == this.value
          );
          this.people = this.hasChoosedUser.map((v) => v.value);
          this.notChoosedUser = this.peoleOptions.filter(
            (v) => v.value != this.value
          );
          let ids = this.notChoosedUser.map((v) => v.value);
          this.peoleOptions.forEach((v) => {
            this.$set(v, "disabled", ids.includes(v.value));
          });
        } else {
          //编辑：多选  回显
          let list = this.value.split(",");
          this.hasChoosedUser = this.peoleOptions.filter((v) =>
            list.includes(v.value)
          );
          this.people = list;
          this.peoleOptions.forEach((v) => {
            this.$set(v, "disabled", list.includes(v.value));
          });
        }
      }
    },

    getData(search = "") {
      if (!this.url) {
        return;
      }
      return new Promise((resolve, reject) => {
        this.$post(this.url, {
          userName: this.userName,
          page: 1,
          pageSize: 9999,
        })
          .then((res) => {
            let { data } = res;
            this.peoleOptions = data.rows || [];
            this.peoleOptions.forEach((v) => {
              let { userName, uuid } = v;
              v.label = userName;
              v.value = uuid;
            });
            this.cloneData = this.peoleOptions;
            this.setForm();
            resolve();
          })
          .catch((_) => {
            this.cloneData = [];
            this.peoleOptions = [];
            reject();
          })
          .finally((_) => {});
      });
    },

    checkBoxChange(ev) {
      //单选
      if (!this.multiple) {
        let { people, peoleOptions } = this;
        //取消禁用
        if (people.length == 0) {
          this.resetSingle();
        }
        //禁用未选择的
        else {
          this.transferData();
          this.hasChoosedUser = this.hasChoosedUser.concat(
            peoleOptions.filter((v) => people.includes(v.value))
          );
        }
      }
      //多选
      else {
        this.multipleChoice();
      }
    },

    // 取消禁用
    resetSingle() {
      this.clonePeople = [];
      this.cloneHasUser = [];
      this.people = [];
      this.hasChoosedUser = [];
      this.notChoosedUser = [];
      this.peoleOptions.forEach((v) => {
        this.$set(v, "disabled", false);
      });
    },
    // 禁用未选择的
    transferData() {
      let { people, peoleOptions } = this;
      this.notChoosedUser = this.notChoosedUser.concat(
        peoleOptions.filter((v) => !people.includes(v.value))
      );
      let ids = this.notChoosedUser.map((v) => v.value);
      this.peoleOptions.forEach((v) => {
        this.$set(v, "disabled", ids.includes(v.value));
      });
    },

    //多选
    multipleChoice() {
      let { people, peoleOptions } = this;
      if (people?.length > 0) {
        this.hasChoosedUser = peoleOptions.filter((v) =>
          people.includes(v.value)
        );
        const peoples = [...new Set(this.people.concat(this.clonePeople))];
        this.people = peoples;
        const mergedArr = this.hasChoosedUser
          .concat(this.cloneHasUser)
          .reduce((acc, obj) => {
            const found = acc.find((item) => item.value === obj.value);
            if (!found) {
              acc.push(obj);
            }
            return acc;
          }, []);
        this.hasChoosedUser = mergedArr;
        setTimeout(() => {
          let ids = this.hasChoosedUser.map((v) => v.value);
          this.peoleOptions.forEach((v) => {
            this.$set(v, "disabled", ids.includes(v.value));
          });
        });
      }
    },

    //tag删除
    handleTagClose(key) {
      if (!this.multiple) {
        this.resetSingle();
      } else {
        //右侧
        const data = this.hasChoosedUser.filter((item) => item.value !== key);
        this.hasChoosedUser = data;
        this.people = this.hasChoosedUser.map((v) => v.value);
        //左侧
        let ids = this.hasChoosedUser.map((v) => v.value);
        this.peoleOptions.forEach((v) => {
          this.$set(v, "disabled", ids.includes(v.value));
        });
        this.cloneHasUser = this.hasChoosedUser;
        this.clonePeople = this.people;
      }
      setTimeout(() => {
        this.$emit("close", this.hasChoosedUser);
      });
    },

    //搜索
    onSearch() {
      this.peoleOptions = [];
      this.clonePeople = this.people;
      this.cloneHasUser = this.hasChoosedUser;
      this.peoleOptions = this.fuzzyQuery(this.cloneData, this.userName);
      if (!this.multiple && this.people.length > 0) {
        this.peoleOptions.forEach((v) => {
          this.$set(v, "disabled", !this.people.includes(v.value));
        });
      }
    },

    fuzzyQuery(list, keyWord) {
      let resultArr = [];
      for (var i = 0; i < list.length; i++) {
        // 判断当前对象的name属性值是否包含关键字
        if (list[i].userName.includes(keyWord)) {
          // 如果包含则将该对象添加到结果数组中
          resultArr.push(list[i]);
        }
      }
      return resultArr;
    },

    openModal() {
      this.cloneHasUser = [];
      this.clonePeople = [];
      this.visible = true;
      this.getData();
    },
    handleOk() {
      this.cloneHasUser = [];
      this.clonePeople = [];
      this.$emit("ok", this.hasChoosedUser);
      this.visible = false;
    },
    handleCancel() {
      this.resetSingle();
      this.$emit("cancel", this.hasChoosedUser);
      this.visible = false;
    },
  },
};
</script>

<style lang="less" scoped="scoped">
.backgroundColor {
  background-color: #f5f5f5;
}
.tag-box {
  cursor: pointer;
  height: auto;
  padding: 0 4px 4px;
  .prompt-box {
    line-height: 22px;

    div {
      display: inline-block;
      margin-top: 4px;
      margin-left: 5px;
      color: #bfbfbf;
      overflow-wrap: anywhere;
    }
    .ant-tag {
      margin-top: 4px;
    }
  }
}
/deep/.ant-modal-body {
  background-color: #f0f2f5 !important;
  padding: 10px !important;
}
.transfer-body {
  line-height: 32px;
  display: flex;
  width: 100%;
  height: 400px;
  justify-content: space-around;
  .transfer-pane {
    padding: 10px;
    background-color: #fff;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    flex: 1;
    .transfer-pane-tools {
      height: 40px;
      display: flex;
      justify-content: space-between;
      .delete-button {
        cursor: pointer;
        color: red;
      }
    }
    .transfer-pane-body {
      width: 100%;
      height: calc(100% - 40px);
      overflow: auto;
      overflow-x: hidden;
      font-size: 14px;
      /deep/.ant-checkbox-group-item {
        display: block;
        margin-bottom: 12px;
      }
      //   label {
      //     display: block !important;
      //     margin-bottom: 12px;
      //   }
      .transfer-pane-item {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 0 12px;
      }
    }
  }
}
.divider-box {
  background-color: #f0f2f5;
  width: 10px;
  height: 100%;
}
.ant-tag {
  font-size: 14px !important;
}
</style>
